/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.wisnu.scs.dao.impl;

import com.wisnu.scs.dao.DbBarangRekapDao;
import com.wisnu.scs.entity.DbBarang;
import com.wisnu.scs.entity.DbBarangKeluar;
import com.wisnu.scs.entity.DbBarangMasuk;
import com.wisnu.scs.entity.DbBarangRekap;
import com.wisnu.scs.error.ErrorMessage;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

public class DbBarangRekapDaoImpl implements DbBarangRekapDao {

    private final SessionFactory sessionFactory;

    public DbBarangRekapDaoImpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public List<DbBarangRekap> selectAll(List<DbBarang> listDbBarang) throws ErrorMessage {
        List<DbBarangMasuk> listDbBarangMasuk = new ArrayList<>();
        List<DbBarangKeluar> listDbBarangKeluar = new ArrayList<>();
        List<DbBarangRekap> listDbBarangRekap = new ArrayList<>();
        Transaction transaction = null;
        Session session = sessionFactory.openSession();
        try {
            transaction = session.beginTransaction();
            listDbBarangMasuk = session.createQuery("from DbBarangMasuk").list();
            listDbBarangKeluar = session.createQuery("from DbBarangKeluar").list();

            for (DbBarang barang : listDbBarang) {
                DbBarangRekap barangRekap = new DbBarangRekap();
                barangRekap.setBarang(barang);
                Integer jumlahMasuk = 0;
                Integer jumlahKeluar = 0;
                for (DbBarangKeluar barangKeluar : listDbBarangKeluar) {
                    if (barangKeluar.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahKeluar += barangKeluar.getJumlah();
                    }
                }
                for (DbBarangMasuk barangMasuk : listDbBarangMasuk) {
                    if (barangMasuk.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahMasuk += barangMasuk.getJumlah();
                    }
                }

                barangRekap.setJumlahMasuk(jumlahMasuk);
                barangRekap.setJumlahKeluar(jumlahKeluar);
                listDbBarangRekap.add(barangRekap);
            }

            transaction.commit();
        } catch (HibernateException exception) {
            if (transaction != null) {
                transaction.rollback();
                throw new ErrorMessage(exception.getMessage());
            }
        } finally {
            session.flush();
            session.close();
        }
        return listDbBarangRekap;
    }

    @Override
    public List<DbBarangRekap> selectByDate(List<DbBarang> listDbBarang, Date date) throws ErrorMessage {
        List<DbBarangMasuk> listDbBarangMasuk = new ArrayList<>();
        List<DbBarangKeluar> listDbBarangKeluar = new ArrayList<>();
        List<DbBarangRekap> listDbBarangRekap = new ArrayList<>();
        Transaction transaction = null;
        Session session = sessionFactory.openSession();
        try {
            transaction = session.beginTransaction();
            listDbBarangMasuk = session.createQuery("from DbBarangMasuk where TANGGAL_MASUK = :date")
                    .setDate("date", date).list();
            listDbBarangKeluar = session.createQuery("from DbBarangKeluar where TANGGAL_KELUAR = :date")
                    .setDate("date", date).list();

            for (DbBarang barang : listDbBarang) {
                DbBarangRekap barangRekap = new DbBarangRekap();
                barangRekap.setBarang(barang);
                Integer jumlahMasuk = 0;
                Integer jumlahKeluar = 0;
                for (DbBarangKeluar barangKeluar : listDbBarangKeluar) {
                    if (barangKeluar.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahKeluar += barangKeluar.getJumlah();
                    }
                }
                for (DbBarangMasuk barangMasuk : listDbBarangMasuk) {
                    if (barangMasuk.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahMasuk += barangMasuk.getJumlah();
                    }
                }

                barangRekap.setJumlahMasuk(jumlahMasuk);
                barangRekap.setJumlahKeluar(jumlahKeluar);
                listDbBarangRekap.add(barangRekap);
            }

            transaction.commit();
        } catch (HibernateException exception) {
            if (transaction != null) {
                transaction.rollback();
                throw new ErrorMessage(exception.getMessage());
            }
        } finally {
            session.flush();
            session.close();
        }
        return listDbBarangRekap;
    }

    @Override
    public List<DbBarangRekap> selectByDateRange(List<DbBarang> listDbBarang, List<Date> dateList) throws ErrorMessage {
        List<DbBarangMasuk> listDbBarangMasuk = new ArrayList<>();
        List<DbBarangKeluar> listDbBarangKeluar = new ArrayList<>();
        List<DbBarangRekap> listDbBarangRekap = new ArrayList<>();
        Transaction transaction = null;
        Session session = sessionFactory.openSession();
        try {
            transaction = session.beginTransaction();
            listDbBarangMasuk = session.createQuery("from DbBarangMasuk where TANGGAL_MASUK >= :firstDate AND TANGGAL_MASUK <= :lastDate")
                    .setDate("firstDate", dateList.get(0))
                    .setDate("lastDate", dateList.get(1))
                    .list();
            listDbBarangKeluar = session.createQuery("from DbBarangKeluar where TANGGAL_KELUAR >= :firstDate AND TANGGAL_KELUAR <= :lastDate")
                    .setDate("firstDate", dateList.get(0))
                    .setDate("lastDate", dateList.get(1))
                    .list();

            for (DbBarang barang : listDbBarang) {
                DbBarangRekap barangRekap = new DbBarangRekap();
                barangRekap.setBarang(barang);
                Integer jumlahMasuk = 0;
                Integer jumlahKeluar = 0;
                for (DbBarangKeluar barangKeluar : listDbBarangKeluar) {
                    if (barangKeluar.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahKeluar += barangKeluar.getJumlah();
                    }
                }
                for (DbBarangMasuk barangMasuk : listDbBarangMasuk) {
                    if (barangMasuk.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahMasuk += barangMasuk.getJumlah();
                    }
                }

                barangRekap.setJumlahMasuk(jumlahMasuk);
                barangRekap.setJumlahKeluar(jumlahKeluar);
                listDbBarangRekap.add(barangRekap);
            }

            transaction.commit();
        } catch (HibernateException exception) {
            if (transaction != null) {
                transaction.rollback();
                throw new ErrorMessage(exception.getMessage());
            }
        } finally {
            session.flush();
            session.close();
        }
        return listDbBarangRekap;
    }

    @Override
    public List<DbBarangRekap> selectByDate(Date date) throws ErrorMessage {
        List<DbBarang> listDbBarang = new ArrayList<>();
        List<DbBarangMasuk> listDbBarangMasuk = new ArrayList<>();
        List<DbBarangKeluar> listDbBarangKeluar = new ArrayList<>();
        List<DbBarangRekap> listDbBarangRekap = new ArrayList<>();
        Transaction transaction = null;
        Session session = sessionFactory.openSession();
        try {
            transaction = session.beginTransaction();
            listDbBarangMasuk = session.createQuery("from DbBarangMasuk where TANGGAL_MASUK = :date")
                    .setDate("date", date).list();
            listDbBarangKeluar = session.createQuery("from DbBarangKeluar where TANGGAL_KELUAR = :date")
                    .setDate("date", date).list();

            for (DbBarangMasuk barangMasuk : listDbBarangMasuk) {
                if (!listDbBarang.contains(barangMasuk.getDbBarang())) {
                    listDbBarang.add(barangMasuk.getDbBarang());
                }
            }

            for (DbBarangKeluar barangKeluar : listDbBarangKeluar) {
                if (!listDbBarang.contains(barangKeluar.getDbBarang())) {
                    listDbBarang.add(barangKeluar.getDbBarang());
                }
            }

            for (DbBarang barang : listDbBarang) {
                DbBarangRekap barangRekap = new DbBarangRekap();
                barangRekap.setBarang(barang);
                Integer jumlahMasuk = 0;
                Integer jumlahKeluar = 0;
                for (DbBarangKeluar barangKeluar : listDbBarangKeluar) {
                    if (barangKeluar.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahKeluar += barangKeluar.getJumlah();
                    }
                }
                for (DbBarangMasuk barangMasuk : listDbBarangMasuk) {
                    if (barangMasuk.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahMasuk += barangMasuk.getJumlah();
                    }
                }

                barangRekap.setJumlahMasuk(jumlahMasuk);
                barangRekap.setJumlahKeluar(jumlahKeluar);
                listDbBarangRekap.add(barangRekap);
            }

            transaction.commit();
        } catch (HibernateException exception) {
            if (transaction != null) {
                transaction.rollback();
                throw new ErrorMessage(exception.getMessage());
            }
        } finally {
            session.flush();
            session.close();
        }
        return listDbBarangRekap;
    }

    @Override
    public List<DbBarangRekap> selectByDateRange(List<Date> dateList) throws ErrorMessage {
        List<DbBarangMasuk> listDbBarangMasuk = new ArrayList<>();
        List<DbBarangKeluar> listDbBarangKeluar = new ArrayList<>();
        List<DbBarangRekap> listDbBarangRekap = new ArrayList<>();
        List<DbBarang> listDbBarang = new ArrayList<>();
        Transaction transaction = null;
        Session session = sessionFactory.openSession();
        try {
            transaction = session.beginTransaction();
            listDbBarangMasuk = session.createQuery("from DbBarangMasuk where TANGGAL_MASUK >= :firstDate AND TANGGAL_MASUK <= :lastDate")
                    .setDate("firstDate", dateList.get(0))
                    .setDate("lastDate", dateList.get(1))
                    .list();
            listDbBarangKeluar = session.createQuery("from DbBarangKeluar where TANGGAL_KELUAR >= :firstDate AND TANGGAL_KELUAR <= :lastDate")
                    .setDate("firstDate", dateList.get(0))
                    .setDate("lastDate", dateList.get(1))
                    .list();
            
            for (DbBarangMasuk barangMasuk : listDbBarangMasuk) {
                if (!listDbBarang.contains(barangMasuk.getDbBarang())) {
                    listDbBarang.add(barangMasuk.getDbBarang());
                }
            }

            for (DbBarangKeluar barangKeluar : listDbBarangKeluar) {
                if (!listDbBarang.contains(barangKeluar.getDbBarang())) {
                    listDbBarang.add(barangKeluar.getDbBarang());
                }
            }

            for (DbBarang barang : listDbBarang) {
                DbBarangRekap barangRekap = new DbBarangRekap();
                barangRekap.setBarang(barang);
                Integer jumlahMasuk = 0;
                Integer jumlahKeluar = 0;
                for (DbBarangKeluar barangKeluar : listDbBarangKeluar) {
                    if (barangKeluar.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahKeluar += barangKeluar.getJumlah();
                    }
                }
                for (DbBarangMasuk barangMasuk : listDbBarangMasuk) {
                    if (barangMasuk.getDbBarang().getIdBarang() == barang.getIdBarang()) {
                        jumlahMasuk += barangMasuk.getJumlah();
                    }
                }

                barangRekap.setJumlahMasuk(jumlahMasuk);
                barangRekap.setJumlahKeluar(jumlahKeluar);
                listDbBarangRekap.add(barangRekap);
            }

            transaction.commit();
        } catch (HibernateException exception) {
            if (transaction != null) {
                transaction.rollback();
                throw new ErrorMessage(exception.getMessage());
            }
        } finally {
            session.flush();
            session.close();
        }
        return listDbBarangRekap;
    }

}
